
package com.borqs.music.tasks;

import static com.borqs.music.http.RequestMethod.POST;
import static com.borqs.music.util.MusicConf.ReqType.MUSIC_SONGS_SYNC;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;

import com.borqs.music.executor.Task;
import com.borqs.music.executor.TaskListener;
import com.borqs.music.http.HttpRequest;
import com.borqs.music.http.HttpResponse;
import com.borqs.music.model.SongInfo;
import com.borqs.music.util.MusicConf;

public class QueryUploadTask extends Task {
    private String songsJSON;

    private String ticket;

    private int requestMode;
    // used for single Mode
    private SongInfo requestInfo;
    private boolean mNeedUpload = false;

    public static final int MODE_LIST = 0;
    public static final int MODE_SINGLE = 1;

    public QueryUploadTask(TaskListener listener, String ticket, List<SongInfo> songs)
            throws JSONException {
        super(listener);
        assert (songs != null && songs.size() > 0) : "song list shoudn't be empty";
        this.songsJSON = encodeJSONString(songs);
        this.ticket = ticket;
        requestMode = MODE_LIST;
    }

    public QueryUploadTask(TaskListener listener, String ticket, SongInfo song)
            throws JSONException {
        super(listener);
        assert (song != null) : "song shoudn't be null";

        requestInfo = song;
        List<SongInfo> songs = new ArrayList<SongInfo>(1);
        songs.add(song);
        this.songsJSON = encodeJSONString(songs);
        this.ticket = ticket;
        requestMode = MODE_SINGLE;
    }

    @Override
    public HttpRequest prepareRequest() {
        Map<String, String> params = new HashMap<String, String>();
        params.put("songlist", songsJSON);

        final String URL = MusicConf.getUrl(MUSIC_SONGS_SYNC);
        HttpRequest requst = new HttpRequest(POST, URL, ticket, params);
        return requst;
    }

    @Override
    public Object handleResponse(HttpResponse resp) throws Exception {
        checkResponse(resp);
        String jsonSongs = resp.asString();
        List<SongInfo> songs = decodeJSONString(jsonSongs);
        if (MODE_LIST == requestMode) {
            return songs;
        } else if (MODE_SINGLE == requestMode) {
            mNeedUpload = (songs.size() > 0);
            return requestInfo;
        }

        return null;
    }

    public boolean isNeedToUpload() {
        if (MODE_SINGLE == requestMode) {
            return mNeedUpload;
        }

        throw new IllegalStateException("Not in MODE_SINGLE");
    }

    public int getMode() {
        return requestMode;
    }

    private static String encodeJSONString(List<SongInfo> songs) throws JSONException {
        JSONStringer jsStringer = new JSONStringer();
        jsStringer.array();
        for (SongInfo song : songs) {
            jsStringer.object();
            jsStringer.key(TITLE).value(song.title);
            jsStringer.key(ARTIST).value(song.artist);
            jsStringer.key(FILE_NAME).value(song.fileName);
            jsStringer.key(FILE_MD5).value(song.fileMd5);
            jsStringer.endObject();
        }
        jsStringer.endArray();
        return jsStringer.toString();
    }

    private static List<SongInfo> decodeJSONString(String jsonSongs) throws Exception {
        JSONArray jarr = new JSONArray(jsonSongs);
        List<SongInfo> songs = new ArrayList<SongInfo>();
        for (int index = 0, len = jarr.length(); index < len; index++) {
            JSONObject jobj = jarr.getJSONObject(index);
            SongInfo song = new SongInfo();
            song.title = jobj.getString(TITLE);
            song.artist = jobj.getString(ARTIST);
            song.fileName = jobj.getString(FILE_NAME);
            song.fileMd5 = jobj.getString(FILE_MD5);
            songs.add(song);
        }

        return songs;
    }

    public static final String TITLE = "title";
    public static final String ARTIST = "singer";
    public static final String FILE_NAME = "filename";
    public static final String FILE_MD5 = "md5";
}
